package com.allwees.bs.module.pms.rest;

import cn.hutool.core.lang.Assert;
import com.alibaba.excel.EasyExcelFactory;
import com.allwees.bs.core.modelbase.branch.BranchUser;
import com.allwees.bs.core.modelbase.branch.EBranchType;
import com.allwees.bs.core.modelbase.exception.BusinessException;
import com.allwees.bs.core.modelbase.importdata.BeansImporter;
import com.allwees.bs.core.modelbase.importdata.ImportDataBean;
import com.allwees.bs.core.modelbase.importdata.ImportResult;
import com.allwees.bs.core.modelbase.vo.R;
import com.allwees.bs.module.core.annotation.PrintLog;
import com.allwees.bs.module.pms.entity.Product;
import com.allwees.bs.module.pms.req.ApplyProductReq;
import com.allwees.bs.module.pms.req.DoEditProductReq;
import com.allwees.bs.module.pms.req.ProductInfoReq;
import com.allwees.bs.module.pms.service.MerchantProductService;
import com.allwees.bs.module.pms.vo.ImportProductReq;
import com.allwees.bs.module.pms.vo.excel.ImportProductSkuBean;
import com.allwees.core.common.util.csv.CsvUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@PrintLog
@Slf4j
@RestController
public abstract class MerchantProductApi<S extends MerchantProductService> extends BaseProductApi<S> {
	@Override
	@GetMapping("/{uuid}")
    public R retrieve(@PathVariable("uuid") String uuid) {
		return R.error("请使用接口：/backstage/api/pms/product/{uuid}");
	}

    /**
     * 新增商品
     *
     * @param req
     * @return
     */
	@PostMapping("/create")
	public R create(@RequestBody ProductInfoReq req) {
		Product product = req.isAutoApply() ? boService.createAndApply(req) : boService.create(req);
        return R.ok("新增商品成功").put("uuid", product.getUuid());
	}

    /**
     * 更新商品
     *
     * @param req
     * @return
     */
    @PutMapping("/{uuid}/edit")
    public R edit(@PathVariable("uuid") String uuid, @RequestBody ProductInfoReq req) {
        req.getBo().setUuid(uuid);
        boService.edit(req);
        return R.ok("保存成功");
    }

    /**
     * 改变商品状态，以编辑商品(已提审后)
     *
     * @param uuid
     * @return
     */
    @PostMapping("/{uuid}/ready_to_edit")
    public R readyToEdit(@PathVariable("uuid") String uuid) {
    	DoEditProductReq req = new DoEditProductReq();
        req.setProductUuid(uuid);
        boService.readyToEdit(req);
        return R.ok("更改商品状态成功");
    }

    /**
     * 上架申请
     *
     * @param req
     * @return
     */
    @PostMapping("/apply")
    public R apply(@RequestBody ApplyProductReq req) {
        boService.apply(req);
        return R.ok("上架申请提交成功");
    }

    /**
     * 批量导入Producth和Sku
     * @param param
     * @return
     * @throws IOException
     */
    protected  <E extends ImportProductSkuBean> R doImportProductsSkus(ImportProductReq param) throws IOException {
        ImportResult importResult = new ImportResult();
        //前端传过来的是"undefined"，这里置空
        param.setStoreUuid(null);
        param.setBranchType(EBranchType.RETAILER);
        BeansImporter<E> importer = (beans, r, p) -> boService.importProductsSkus(beans, importResult,param);
        if(param.isXls()){
            doImportExcelData(param, importResult, importer);
        } else if (param.isCsv()){
            doImportCvsData(param, importResult, importer);
        } else {
            importResult.setSuccess(false);
            importResult.addErrorMsg("目前仅支持导入Excel和CSV格式的文件~");
        }
        return R.ok(importResult);
    }


    private <T extends ImportDataBean> void doImportExcelData(ImportProductReq param, ImportResult importResult, BeansImporter<T> beansImporter) throws IOException {
        InputStream inputStream = param.getFiledata().getInputStream();
        Class<? extends ImportDataBean> header = param.getUploadExcelPlatform().getClz();
        log.info(">>>开始解析excel文件...");
        long start = System.currentTimeMillis();
        List<T> beans = EasyExcelFactory.read(inputStream).sheet(0).head(header).doReadSync();
        log.info(">>>结束解析excel文件,耗时：{} 毫秒,行数：{}",System.currentTimeMillis() - start,beans.size());
        if(CollectionUtils.isEmpty(beans)){
            return;
        }
        Assert.isTrue(beans.size() <= 5001,"每次最多上传5000条数据~");
        doImportData(beans,importResult,beansImporter,param);
    }

    private <T extends ImportDataBean> void doImportCvsData(ImportProductReq param, ImportResult importResult, BeansImporter<T> beansImporter) throws IOException {
        Class<? extends ImportDataBean> header = param.getUploadExcelPlatform().getClz();
        InputStream inputStream = param.getFiledata().getInputStream();
        log.info(">>>开始解析csv文件...");
        long start = System.currentTimeMillis();
        List<T> beans = CsvUtil.readByColumnName(inputStream, header);
        log.info(">>>结束解析csv文件,耗时：{} 毫秒,行数：{}",System.currentTimeMillis() - start,beans.size());
        if(CollectionUtils.isEmpty(beans)){
            return;
        }
        Assert.isTrue(beans.size() <= 5001,"每次最多上传5000条数据~");
        doImportData(beans,importResult,beansImporter,param);
    }

    private <T extends ImportDataBean> void doImportData(List<T> beans,ImportResult importResult,BeansImporter<T> beansImporter,ImportProductReq param){
        try {
            long startTime = System.currentTimeMillis();
            param.setBranchUser(checkImportUser());
            beansImporter.doImport(beans, importResult,param);
            if (importResult.isSuccess()) {
                String msg = "导入数据完成，耗时 " + ((System.currentTimeMillis() - startTime) / 1000) + " 秒。";
                importResult.addInfoMsg(msg);
            } else {
                String errMsg = "导入的文件格式错误或含有无效数据，请检查。";
                importResult.addInfoMsg(errMsg);
            }
        } catch (Exception e) {
            log.error("数据导入出错:", e);
            importResult.clearNewNum();
            importResult.setSuccess(false);
        }
    }

    protected BranchUser checkImportUser() {
        BranchUser user = getCurrentUser();
        if (user == null) {
            throw new BusinessException("当前用户未登录");
        }
        switch (user.getBranchType()) {
            case SUPPLIER:
                if (user.getSupplierUuid() == null) {
                    throw new BusinessException("当前登录用户不是供应商");
                }
                break;
            case RETAILER:
                if (user.getRetailerUuid() == null) {
                    throw new BusinessException("当前登录用户不是零售商");
                }
                break;
            default:
                throw new BusinessException("当前登录用户不是商户（供应商或零售商）");
        }
        return user;
    }
}
